//获取文件大小（文件属性）
//判断文件是否存在
//向文件写入数据
//从文件读取数据
//创建目录
#ifndef __MY_UTIL__
#define __MY_UTIL__
#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
#include <sys/stat.h>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h>

namespace aod{
  class FileUtil{
    private:
      std::string _name;//文件路径名称
    public:
      FileUtil(const std::string name):_name(name)
      {}
      //判断文件是否存在
      bool Exits()
      {
        int ret = access(_name.c_str(), F_OK);
        if(ret != 0) return false;//未找到该文件

        return true;
      }
      //获取文件大小
      size_t Size()
      {
        //判断文件是否存在
        if(this->Exits() == false) return 0;
        //st保存文件的各项属性
        struct stat st;
        int ret = stat(_name.c_str(), &st);
        if(ret != 0)
        {
          std::cout << "[FileUtil] stat fail" << std::endl;
          return 0;
        }

        return st.st_size;
      }
      //读取文件数据到body中
      bool GetContent(std::string *body)
      {
        std::ifstream ifs;
        ifs.open(_name, std::ios::binary);
        if(!ifs.is_open())
        {
          //打开失败
          std::cout << "[FileUtil] open fail" << std::endl;
          return false;
        }
        size_t len = this->Size();
        body->resize(len);
        ifs.read(&(*body)[0],len);
        if(!ifs.good())
        {
          //读取出错
          std::cout << "[FileUtil] read fail" << std::endl;
          ifs.close();
          return false;
        }
        ifs.close();
        return true;
      }
      //像文件中写入数据body
      bool SetContent(const std::string &body)
      {
        std::ofstream ofs;
        ofs.open(_name, std::ios::binary);
        if(!ofs.is_open())
        {
          //文件打开失败
          std::cout << "[FileUtil] open fail" << std::endl;
          return false;
        }
        ofs.write(body.c_str(), body.size());
        if(!ofs.good())
        {
          //写入失败
          std::cout << "[FileUtil] write fail" << std::endl;
          ofs.close();
          return false;
        }
        ofs.close();
        return true;
      }
      //创建目录
      bool CreateDirectory()
      {
        if(this->Exits()) return true;//已经存在该目录了

        int ret = mkdir(_name.c_str(), 0777);
        if(ret != 0)
        {
          //创建目录失败
          std::cout << "[FileUtil] dir make fail" << std::endl;
          return false;
        }
        return true;
      }
  };//class FileUtil

  class JsonUtil{
    public:
      static bool Serialize(Json::Value &root, std::string *body)
      {
        Json::StreamWriterBuilder swb;
        std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
        std::stringstream ss;
        if(sw->write(root, &ss))
        {
          //写入失败
          std::cout << "[JsonUtil] write fail" << std::endl; 
          return false;
        }
        *body = ss.str();
        return true;
      }
      static bool Deserialize(const std::string &body, Json::Value *root)
      {
        Json::CharReaderBuilder crb;
        std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
        std::string err;
        if(!cr->parse(body.c_str(),body.c_str()+body.size(),root,&err))
        {
          //划分失败
          std::cout << "[JsonUtil] parse fail" << std::endl;
          return false;
        }
        return true;
      }
  };//class JsonUtil 
}//namespace aod
#endif
